<?php
/**
 * <b>RUBIK IT Solution & Development ltd.</b>
 *
 * PROJECT		: Rubik Ultimate Framework
 * @version 	: 1.1
 * COPYRIGHT    : 2008
 * ------------------------------------------------------
 * 
 * Created on	:  Jul 7, 2008
 * 
 */

// no direct access
defined ( '_FW_EXEC' ) or die ( 'Restricted access' );
RLibImporter::cls( "xml.JSimpleXML" );
RCoreImporter::cls( "sysObjects.SysRequest" );

class PluginManager extends Object {
	
	var $xml;
	var $_group;
	/**
	 * 
	 *
	 * @param string $pluginGroup - Position of Plugin
	 */
	function __construct($pluginGroup) {
		unset ( $this->xml );
		$this->xml = new JSimpleXML ( );
		$this->_group = $pluginGroup;
		$file = $this->_getConfigFile ( $pluginGroup );
		if ($file)
			$this->_loadFile ( $file );
		return;
	}
	
	/**
	 * Get config file follow position
	 *
	 * @param string $pluginGroup
	 * @return mix
	 */
	function _getConfigFile($pluginGroup) {
		$fileXMLConfig = SYS_PLUGIN_CONFIG_PATH . $pluginGroup . '.plugins.xml';

		if (file_exists ( $fileXMLConfig )) {
			return $fileXMLConfig;
		}
		$this->setError ( "Plugin config file: <b>$fileXMLConfig</b> doesn't exists." );
		RError::raiseWarning ( 300, $this->getError () );
		return false;
	}
	
	/**
	 * load file XML
	 *
	 * @param string $filePath - Path to XML file
	 * @return unknown
	 */
	function _loadFile($filePath) {
		return $this->xml->loadFile ( $filePath );
	}
	
	/**
	 * Get Children Node of XML document
	 *
	 * @return XML Tag
	 */
	function _getChildren() {
		if (! empty ( $this->xml->document ))
			return $this->xml->document->children ();
		return false;
	}
	
	/**
	 * Get Tag of Active
	 *
	 * @param XML Tag $XMLTag
	 */
	function &_getTagPlugins($XMLTag, &$runtimeParams) {
		$numberOfPlugin = count ( $XMLTag );
		for($i = 0; $i < $numberOfPlugin; $i ++) {
			$elementsOfPlugin = $XMLTag [$i]->children ();
			$pluginAttrs = $XMLTag [$i]->attributes ();
			
			$pluginName = $pluginAttrs ['name'];
			$phpFile = $pluginAttrs ['file'];
			
			$numberOfElement = count ( $elementsOfPlugin );
			// incase we have shome children
			if ($numberOfElement != 0) {
				$viewElementOfPlugin = $this->_getFirstNode ( $elementsOfPlugin, "active" );
				if (! empty ( $viewElementOfPlugin )) {
					$viewElementOfPlugin = $viewElementOfPlugin->children ();
					if (! ($this->isActivePlugin ( $viewElementOfPlugin ))) {
						continue;
					}
				}
				
				$params = $this->_getFirstNode ( $elementsOfPlugin, "params" );
				if (! empty ( $params )) {
					$params = $params->children ();
					$pluginParams = $this->_getPluginParams ( $params );
				}
				
				// php Content
				if (empty ( $pluginName ) && empty ($phpFile)) {
					// Content plugin
					$contentOfPlugin = $this->_getFirstNode ( $elementsOfPlugin, "content" );
					$contentOfPlugin = $contentOfPlugin->data ();
					
					eval($contentOfPlugin);
					continue;
				}
			}

			// If have the name --> mean this must have a class
			if ($pluginName) {
				$this->_runPlugin ( $pluginName, $pluginParams, $runtimeParams );
			}
			
			// case of php file.
			if ($phpFile) {
				require(SYS_PLUGIN_PATH.$phpFile);
			}
		}
		
		return $runtimeParams;
	}
	
	/**
	 * Get the first node with the $nodeName in the $listNode
	 *
	 * @param array XML element $listNode
	 * @param string $nodeName
	 * @return JSimpleXMLElement
	 */
	function _getFirstNode($listNode, $nodeName) {
		foreach ( $listNode as $node ) {
			if ($node->name () == $nodeName) {
				return $node;
			}
		}
		return null;
	}
	
	/**
	 * Get Data from XMLTag
	 *
	 * @param JSimpleXMLElement Object $XMLTag
	 * @return string data
	 */
	function getData($XMLTag) {
		return $XMLTag->_data;
	}
	
	/**
	 * Print data from XML Tag
	 *
	 * @param JSimpleXMLElement Object $XMLTag
	 */
	function printData($XMLTag) {
		echo $this->getData ( $XMLTag );
	}
	
	/**
	 * run the plugin
	 *
	 * @param string $pluginName example: 'login'
	 * @param array $pluginParams - Parameters to use in class AbstractPlugin
	 */
	function _runPlugin($pluginName, $pluginParams, &$runtimeParams) {
		$plugin = &SystemSite::getPlugin($pluginName, $this->_group, $pluginParams);
		if ($plugin->isActive ()) {
			return $plugin->run($runtimeParams);
		}
	}
	
	/**
	 * Show all Plugins
	 *
	 * @param mixe $runtimeParams the parameterWhen runtime
	 * @return $runtimeParams
	 */
	function &runPlugins(&$runtimeParams) {
		if ($xmlTag = $this->_getChildren ())
			return $this->_getTagPlugins ( $xmlTag, $runtimeParams );
		return false;
	
	}
	
	/**
	 * Get Parameters of Plugin
	 *
	 * @param array of JSimpleXMLElement Object $paramElement
	 * @return Object contain Parameters
	 */
	function _getPluginParams($paramElement) {
		$numberOfParamElement = count ( $paramElement );
		$name = new stdClass ( );
		for($j = 0; $j < $numberOfParamElement; $j ++) {
			$paramName = $paramElement [$j]->_name;
			$name->$paramName = $paramElement [$j]->_data;
		}
		return $name;
	}
	
	/**
	 * Check the plugin is run or not
	 * NOTE: This function can be override when need to special treat
	 *
	 * @param array of JSimpleXMLElement $viewElement
	 * 
	 * @return boolean
	 */
	function isActivePlugin($viewElement) {
		$numberOfActiveElement = count ( $viewElement );
		
		$hasDisable = false;
		for($j = 0; $j < $numberOfActiveElement; $j ++) {
			$viewArr = $viewElement [$j]->attributes ();
			$viewName = $viewElement [$j]->name ();
			
			$sysResource = SysRequest::getResource ();
			$menuResource = new SiteResource ( );
			$menuResource->setValueFromRequest ( $viewArr );
			if (! empty ( $viewArr ['group'] )) {
				$userGroup = explode ( ',', $viewArr ['group'] );
			}
			
			if ($viewName == 'disable') {
				if (empty ( $userGroup ) || ! $this->_checkUserGroup ( $userGroup )) {
					if ($sysResource->checkCover ( $menuResource )) {
						return false;
					}
				}
				$hasDisable = true;
			} else if ($viewName == 'enable') {
				if (empty ( $userGroup ) || $this->_checkUserGroup ( $userGroup )) {
					if ($sysResource->checkCover ( $menuResource )) {
						return true;
					}
				}
			}
		}
		return $hasDisable;
	}
	
	/**
	 * Check Current user in Group?
	 *
	 * @param array of UserGroup $arrGroups
	 * @return true|false - true if user in group
	 */
	function _checkUserGroup($arrGroups) {
		//the group check.
		if (class_exists('SysAuthenticate')) {
			$userType = SysAuthenticate::getUserType();
			if (in_array($userType, $arrGroups)) {
				return true;
			}
			
			return false;
		}
		return true;
	}
}

?>